﻿//*** Guidance generated code ***//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Dispatcher;
using $prjsn$.RestApi;
using ProjectBase.Core;
using ProjectBase.Core.Service;

using $prjsn$.Common.Business;

namespace $safeprojectname$.RestApi
{
    public class ServiceSelector : DefaultHttpControllerSelector //IHttpControllerSelector
    {
        readonly HttpConfiguration _configuration;
        static IDictionary<string, Type> _serviceTypes;
        static IDictionary<string, HttpControllerDescriptor> _serviceMapping;

        #region Constructor
        static ServiceSelector()
        {
            
        }
        public ServiceSelector(HttpConfiguration configuration)
            : base(configuration)
        {
            _configuration = configuration;
        }
        #endregion Constructor

        public override HttpControllerDescriptor SelectController(HttpRequestMessage request)
        {
            var name = (GetControllerName(request) + "Service");

            Type type;
            if (ServiceTypes.TryGetValue(name, out type))
            {
                return new HttpControllerDescriptor(_configuration, name, type);
            }
            return base.SelectController(request);
        }

        public override IDictionary<string, HttpControllerDescriptor> GetControllerMapping()
        {
            return ServiceMapping;
        }

        protected virtual IDictionary<string, HttpControllerDescriptor> ServiceMapping
        {
            get
            {
                var mapping = _serviceMapping;
                if (mapping.IsNull())
                {
                    mapping = new Dictionary<string, HttpControllerDescriptor>(StringComparer.InvariantCultureIgnoreCase);

                    foreach (var pair in ServiceTypes)
                    {
                        var name = pair.Key;
                        var type = pair.Value;

                        var descriptor = new HttpControllerDescriptor(_configuration, name, type);
                        mapping[name] = descriptor;

                    }

                    _serviceMapping = mapping;
                }

                return mapping;
            }
        }

        protected static IDictionary<string, Type> ServiceTypes
        {
            get
            {
                var serviceTypes = _serviceTypes;
                if (serviceTypes.IsNull())
                {
                    // the StructureMap settings
                    serviceTypes = IoC
                        .StructureMapFactoryProvider
                        .GetPluginTypes(t => t.PluginType.Name.Contains("Service")
                                             && t.PluginType.IsSubclassOf(typeof (ApiController)))
                        ;

                    // the CustomList Types
                    var customListTypeFacade = Factory.CreateInstance<ICustomListTypeFacade>();
                    customListTypeFacade.Change += Clear;
                    var customListTypes = customListTypeFacade.GetAll();

                    // all of them will use CustomListService
                    var customListDiscriminator = "CustomListService";
                    Type customService;

                    if (serviceTypes.TryGetValue(customListDiscriminator, out customService))
                    {
                        foreach (var customType in customListTypes)
                        {
                            // e.g. "MyNewCodeListService"
                            var customName = (customType.Description + "Service");
                            serviceTypes[customName] = customService;
                        }
                    }
                    _serviceTypes = serviceTypes;
                }
                return serviceTypes;
            }
        }

        static void Clear(object sender, EventArgs e)
        {
            _serviceTypes = null;
        }
    }
}
